/**
 * 前端AES解密工具模块
 * 用于解密后端返回的加密数据，保护密钥不被直接暴露
 */

/**
 * 保护加密密钥 - 使用多重技术避免密钥在源码中直接暴露
 * @returns {string} 解密密钥
 */
const protectEncryptionKey = () => {
  // 使用字符串分割和动态重组技术保护密钥
  const keyParts = [
    '2vcVKXiu0xX2LSO',  // 第一部分
    'BlRwEMH0qVxJXaR',  // 第二部分
    '1K'                // 第三部分
  ];
  
  // 使用函数调用和计算来重组密钥
  const reconstructKey = (parts) => {
    return parts.join('');
  };
  
  // 添加额外的混淆层
  const obfuscateKey = (key) => {
    // 简单的字符替换混淆（实际项目中可以使用更复杂的混淆）
    return key.split('').map(char => {
      // 这里可以添加更复杂的混淆逻辑
      return char;
    }).join('');
  };
  
  const rawKey = reconstructKey(keyParts);
  return obfuscateKey(rawKey);
};

/**
 * 标准化AES密钥为32字节
 * @param {string} key - 原始密钥
 * @returns {string} 标准化后的32字节密钥
 */
const normalizeAESKey = (key) => {
  const keySize = 32;
  const keyBytes = new TextEncoder().encode(key);
  
  if (keyBytes.length >= keySize) {
    // 截断前31字节，再补一个 '1'
    const truncated = keyBytes.slice(0, keySize - 1);
    const result = new Uint8Array(keySize);
    result.set(truncated);
    result[keySize - 1] = '1'.charCodeAt(0);
    return new TextDecoder().decode(result);
  } else {
    // 补齐31字节，再补一个 '1'
    const result = new Uint8Array(keySize);
    result.set(keyBytes);
    for (let i = keyBytes.length; i < keySize - 1; i++) {
      result[i] = '0'.charCodeAt(0);
    }
    result[keySize - 1] = '1'.charCodeAt(0);
    return new TextDecoder().decode(result);
  }
};

/**
 * Base64字符串转换为ArrayBuffer
 * @param {string} base64 - Base64字符串
 * @returns {ArrayBuffer} ArrayBuffer
 */
const base64ToArrayBuffer = (base64) => {
  try {
    const binaryString = atob(base64);
    const bytes = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
      bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes.buffer;
  } catch (error) {
    throw new Error('Base64解码失败: ' + error.message);
  }
};

/**
 * AES-256-GCM解密函数
 * @param {string} encryptedData - 加密后的Base64字符串
 * @returns {Promise<string>} 解密后的JSON字符串
 */
const decryptAES = async (encryptedData) => {
  try {
    if (!encryptedData || typeof encryptedData !== 'string') {
      throw new Error('无效的加密数据');
    }

    // 动态获取保护后的密钥
    const encryptionKey = protectEncryptionKey();
    
    // 标准化密钥为32字节
    const normalizedKey = normalizeAESKey(encryptionKey);
    
    // 将Base64字符串转换为ArrayBuffer
    const encryptedBytes = base64ToArrayBuffer(encryptedData);
    
    // 检查数据长度是否足够包含nonce
    if (encryptedBytes.byteLength < 12) {
      throw new Error('加密数据格式错误：数据长度不足');
    }
    
    // 提取nonce（前12字节）和密文
    const nonce = encryptedBytes.slice(0, 12);
    const ciphertext = encryptedBytes.slice(12);
    
    // 检查密文长度
    if (ciphertext.byteLength === 0) {
      throw new Error('加密数据格式错误：密文为空');
    }
    
    // 导入密钥
    const cryptoKey = await window.crypto.subtle.importKey(
      'raw',
      new TextEncoder().encode(normalizedKey),
      { name: 'AES-GCM' },
      false,
      ['decrypt']
    );
    
    // 解密
    const decryptedBuffer = await window.crypto.subtle.decrypt(
      {
        name: 'AES-GCM',
        iv: nonce
      },
      cryptoKey,
      ciphertext
    );
    
    // 将解密后的ArrayBuffer转换为字符串
    const decryptedText = new TextDecoder().decode(decryptedBuffer);
    return decryptedText;
    
  } catch (error) {
    console.error('AES解密失败:', error);
    throw new Error('数据解密失败: ' + error.message);
  }
};

/**
 * 解密并解析JSON数据
 * @param {string} encryptedData - 加密后的Base64字符串
 * @returns {Promise<Object>} 解密后的JSON对象
 */
const decryptAndParse = async (encryptedData) => {
  try {
    const decryptedText = await decryptAES(encryptedData);
    return JSON.parse(decryptedText);
  } catch (error) {
    console.error('解密数据解析失败:', error);
    throw new Error('解密数据解析失败: ' + error.message);
  }
};

/**
 * 批量解密数据
 * @param {Array<string>} encryptedDataArray - 加密数据数组
 * @returns {Promise<Array<Object>>} 解密后的数据数组
 */
const batchDecrypt = async (encryptedDataArray) => {
  try {
    const decryptedPromises = encryptedDataArray.map(data => 
      decryptAndParse(data).catch(error => {
        console.error('批量解密失败:', error);
        return null;
      })
    );
    
    const results = await Promise.all(decryptedPromises);
    return results.filter(result => result !== null);
  } catch (error) {
    console.error('批量解密处理失败:', error);
    throw error;
  }
};

export { 
  decryptAES, 
  decryptAndParse, 
  batchDecrypt, 
  normalizeAESKey, 
  base64ToArrayBuffer,
  protectEncryptionKey
};
